#include <bits/stdc++.h>
using namespace std;

const int R = 1e5 + 10;
vector<int> son[R];
long long a[R], b[R], c[R], need[R], dis[R];
int main()
{
	// freopen("tree.in", "r", stdin);
	// freopen("tree.out", "w", stdout);
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int n, y, i, j;
	long long h, maxneed = 0, maxneedx, cnt, x;
	cin >> n;
	for (i = 1; i <= n; ++i)
	{
		cin >> a[i] >> b[i] >> c[i];
		cnt = h = 0;
		for (x = 1; h < a[i]; ++x)
		{
			if (b[i] + x * c[i] <= 1)
			{
				x = a[i] - h;
				break;
			}
			else
			{
				h += max(b[i] + x * c[i], 1ll);
			}
		}
		if (x > maxneed)
		{
			maxneed = x;
			maxneedx = i;
		}
		maxneed = max(maxneed, cnt);
	}
	for (i = 1; i < n; ++i)
	{
		cin >> x >> y;
		son[x].push_back(y);
		son[y].push_back(x);
	}
	queue<int> q;
	q.push(1);
	memset(dis, 0x3f, sizeof(dis));
	dis[1] = 0;
	while (!q.empty())
	{
		x = q.front();
		q.pop();
		for (int to : son[x])
		{
			if (dis[to] == 0x3f3f3f3f)
			{
				dis[to] = dis[x] + 1;
				q.push(to);
			}
		}
	}
	cout << dis[maxneedx] + maxneed << '\n';
	return 0;
}
// QwQ
// #include <bits/stdc++.h>
// using namespace std;
//
// using ll = long long;
////segment tree
// struct
//{
//	int l, r, val;
// } t[R * 4];
// void build(int k, int l, int r)
//{
//	t[k].l = l, t[k].r = r;
//	if (l == r)
//	{
//
//		return;
//	}
//	int mid = (l + r) >> 1;
//	build(lc(k), l, mid);
//	build(rc(k), mid + 1, r);
//	pushup(k);
// }
// void update(int k, int x, int y, int val)
//{
//
//	pushdown(k);
//
//	pushup(k);
// }
// ll query(int k, int x, int y)
//{
//	if (x <= t[k].l && t[k].r <= y)
//	{
//		return t[k].val;
//	}
//	pushdown(k);
//	int mid = (t[k].l + t[k].r) >> 1;
//	if (x <= mid)
//	{
//		res = query(lc(k), x, y);
//	}
//	if (y > mid)
//	{
//		res += query(rc(k), x, y);
//	}
//	return res;
// }
//
////fhq
// struct
//{
//	int son[2], val, sz;
//	unsigned int key;
// } t[R];
// void split(int k, int sz, int &x, int &y)
//{
//	if (!k)
//	{
//		x = y = 0;
//		return;
//	}
//	if (t[lc(k)].sz + 1 <= sz)
//	{
//		x = k;
//		split(rc(k), sz - t[lc(k)].sz - 1, rc(x), y);
//	}
//	else
//	{
//		y = k;
//		split(lc(k), sz, x, lc(y));
//	}
//	pushup(k);
// }
// int merge(int x, int y)
//{
//	if (!x || !y)
//	{
//		return x | y;
//	}
//	if (t[x].key < t[y].key)
//	{
//		rc(x) = merge(rc(x), y);
//		pushup(x);
//		return x;
//	}
//	else
//	{
//		lc(y) = merge(x, lc(y));
//		pushup(y);
//		return y;
//	}
// }
//
////dijkstra
// void dijkstra()
//{
//	memset(dis, 0x3f, sizeof(dis));
//	dis[1] = 0;
//	priority_queue<Edge> q;
//	q.push({1, 0});
//	while (!q.empty())
//	{
//		x = q.top().x;
//		q.pop();
//		if (!b[x])
//		{
//			b[x] = true;
//			for (i = head[x]; i; i = e[i].nxt)
//			{
//				to = e[i].to;
//				len = e[i].len;
//				if (dis[x] + len < dis[to])
//				{
//					dis[to] = dis[x] + len;
//					q.push({to, dis[to]});
//				}
//			}
//		}
//	}
// }
//
////spfa
// void spfa()
//{
//	queue<int> q;
//	q.push(1);
//	memset(dis, 0x3f, sizeof(dis));
//	dis[1] = 0;
//	while (!q.empty())
//	{
//		x =
//	}
// }
//
////isap
// void bfs()
//{
//	queue<int> q;
//	q.push(t);
//	depcnt[dep[t] = 1] = 1;
//	while (!q.empty())
//	{
//		x = q.front();
//		q.pop();
//		for (i = head[x]; ~i; i = e[i].nxt)
//		{
//			to = e[i].to;
//			if (!dep[to])
//			{
//				dep[to] = dep[x] + 1;
//				++depcnt[dep[to]];
//				q.push(to);
//			}
//		}
//	}
// }
// int dfs(int x, int flow)
//{
//
// }
//
// int main()
//{
//	freopen("", "r", stdin);
//	freopen("", "w", stdout);
//	ios::sync_with_stdio(false);
//	cin.tie(nullptr);
//	cout.tie(nullptr);
//
//	return 0;
// }
